package com.htthorizon.powersupply.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.htthorizon.powersupply.domain.RdsGridTgPowerDf;
import com.htthorizon.powersupply.domain.TgLoadMonitor;
import com.htthorizon.powersupply.mapper.RdsGridTgPowerDfMapper;
import com.htthorizon.powersupply.service.RdsGridTgPowerDfService;
import com.htthorizon.powersupply.service.TgLoadItemService;
import com.htthorizon.powersupply.service.TgLoadMonitorService;
import com.htthorizon.powersupply.utils.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.lang.Math.pow;
import static java.lang.Math.sqrt;

/**
 * @author Brilliant
 * @description 针对表【rds_grid_tg_power_df】的数据库操作Service实现
 * @createDate 2025-01-16 15:47:38
 */
@Service
@Slf4j
public class RdsGridTgPowerDfServiceImpl extends ServiceImpl<RdsGridTgPowerDfMapper, RdsGridTgPowerDf>
        implements RdsGridTgPowerDfService {

    @Autowired
    private TgLoadMonitorService tgLoadMonitorService;

    @Autowired
    private TgLoadItemService tgLoadItemService;


    @Override
    public Map<String, Object> getChartPower(String meterId) {
        String dataDt = DatePattern.PURE_DATE_FORMAT.format(new Date());
        HashMap<String, Object> map = new HashMap<>();
        map.put("use", new String[96]);
        map.put("disuse", new String[96]);
        map.put("date", dataDt);
        LambdaQueryWrapper<RdsGridTgPowerDf> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RdsGridTgPowerDf::getMeterId, meterId);
        wrapper.eq(RdsGridTgPowerDf::getDataDt, dataDt);
        wrapper.in(RdsGridTgPowerDf::getDataType, "1", "5");
        List<RdsGridTgPowerDf> rdsGridTgPowerDfs = this.list(wrapper);
        if (!CollectionUtils.isEmpty(rdsGridTgPowerDfs)) {
            for (RdsGridTgPowerDf rdsGridTgPowerDf : rdsGridTgPowerDfs) {
                if ("1".equals(rdsGridTgPowerDf.getDataType())) {
                    String[] use = rdsGridTgPowerDf.mapArray();
                    map.put("use", use);
                } else if ("2".equals(rdsGridTgPowerDf.getDataType())) {
                    String[] disuse = rdsGridTgPowerDf.mapArray();
                    map.put("use", disuse);
                }
            }
        }
        return map;
    }

    @Override
    public void compute() {
        log.info("开始计算重过载");
        compute(1, new ArrayList<>());
    }

    public void compute(int page, List<RdsGridTgPowerDf> list) {
        int pageSie = 1000;
//        log.info("开始计算第{}页重过载数据,上一次计算遗留数据条数:{}", page, list.size());
        String dateDt = DatePattern.PURE_DATE_FORMAT.format(new Date());
        QueryWrapper<RdsGridTgPowerDf> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("data_dt", dateDt);
        queryWrapper.orderByAsc("meter_id");

        Page<RdsGridTgPowerDf> rdsGridTgPowerDfPage = new Page<>(page, pageSie);
        Page<RdsGridTgPowerDf> result = this.page(rdsGridTgPowerDfPage, queryWrapper);
        List<RdsGridTgPowerDf> records = result.getRecords();
        list.addAll(records);
        Map<String, List<RdsGridTgPowerDf>> meterMap = list.stream().collect(Collectors.groupingBy(RdsGridTgPowerDf::getMeterId));
        meterMap.forEach((k, v) -> {
            if (v.size() > 1) {
                RdsGridTgPowerDf rdsGridTgPowerDf1 = v.get(0);
                double cap = Double.parseDouble(rdsGridTgPowerDf1.getTgCap());
                if (cap == 0D) {
                    return;
                }
                String meterId = rdsGridTgPowerDf1.getMeterId();
                String tgType = rdsGridTgPowerDf1.getTgType();
                RdsGridTgPowerDf rdsGridTgPowerDf2 = v.get(1);
                JSONObject entries = new JSONObject(rdsGridTgPowerDf1);
                JSONObject entries2 = new JSONObject(rdsGridTgPowerDf2);
                String timeFormat = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
                List<TgLoadMonitor> tgLoadMonitors = new ArrayList<>(97);
                LambdaQueryWrapper<TgLoadMonitor> tgLoadMonitorQueryWrapper = new LambdaQueryWrapper<>();
                tgLoadMonitorQueryWrapper.eq(TgLoadMonitor::getMeterId, k);
                tgLoadMonitorQueryWrapper.in(TgLoadMonitor::getLoadType,"三相过载","三相重载","三相预重载");
                tgLoadMonitorQueryWrapper.eq(TgLoadMonitor::getDataDt, dateDt);
                tgLoadMonitorService.remove(tgLoadMonitorQueryWrapper);
                for (int i = 1; i <= 96; i++) {
                    try {
                        Object o = entries.get("val" + i);
                        Object o1 = entries2.get("val" + i);
                        if(o == null || o1 == null){
                            continue;
                        }
                        double v1 = Double.parseDouble((String) o);
                        double v2 = Double.parseDouble((String) o1);
                        double vq1 = pow(v1, 2);
                        double vq2 = pow(v2, 2);
                        double sqrt = sqrt(vq1 + vq2);
                        double reuslt = (sqrt / cap) * 100;
                        String loadType = "";
                        if (reuslt >= 100) {
                            loadType = "三相过载";
                        } else if (reuslt >= 80) {
                            loadType = "三相重载";
                        } else if (reuslt >= 70) {
                            loadType = "三相预重载";
                        }
                        if (reuslt >= 70) {
                            TgLoadMonitor tgLoadMonitor = new TgLoadMonitor();
                            BeanUtils.copyProperties(rdsGridTgPowerDf1, tgLoadMonitor, "id");
                            tgLoadMonitor.setLoadType(loadType);
                            tgLoadMonitor.setStdCountyOrgNm(this.map(tgLoadMonitor.getStdCountyOrgNm()));
                            tgLoadMonitor.setTime(i);
                            tgLoadMonitor.setLoadFactor(NumberUtil.round(reuslt, 2) + "%");
                            tgLoadMonitor.setApperTime(timeFormat + " " + TimeUtil.getTimeByIndex(i));
                            tgLoadMonitor.setSign(this.sign(meterId));
                            tgLoadMonitor.setLabel(this.label(meterId));
                            tgLoadMonitor.setTgType(tgType);
                            tgLoadMonitors.add(tgLoadMonitor);

                        }

                    } catch (Exception e) {
                        log.error("判定重过载异常", e);
                    }
                }
                tgLoadMonitorService.saveBatch(tgLoadMonitors);
                records.removeAll(v);
            }
        });
        if (result.hasNext()) {
            page++;
            compute(page, records);

        }
    }


    private String map(String tgNm) {
        if (tgNm.contains("城东")) {
            return "城东";
        } else if (tgNm.contains("天元")) {
            return "天元";
        } else if (tgNm.contains("渌口")) {
            return "渌口";
        } else if (tgNm.contains("醴陵")) {
            return "醴陵";
        } else if (tgNm.contains("攸县")) {
            return "攸县";
        } else if (tgNm.contains("茶陵")) {
            return "茶陵";
        } else if (tgNm.contains("炎陵")) {
            return "炎陵";
        } else {
            return tgNm;
        }
    }

    private Map<String, String> map = new HashMap<>();
    private Map<String, String> labelMap = new HashMap<>();
    private Map<String, String> lineNmlabelMap = new HashMap<>();
    private Map<String, String> tglabelMap = new HashMap<>();


    @Override
    public String sign(String meterId) {
        if (map.isEmpty()) {
            tgLoadItemService.list().forEach(item -> {
                map.put(item.getMeterId(), item.getLoadType());
            });
        }
        String s = map.get(meterId);
        if (s == null) {
            return null;
        }
        if(s.contains("重载")){
            return "24年重载";
        }else if (s.contains("过载")){
            return "24年过载";
        } else if (s.contains("停运")) {
            return "24年停运";
        }else{
            return null;
        }
    }

    @Override
    public String label(String meterId) {
        if (labelMap.isEmpty()) {
            tgLoadItemService.list().forEach(item -> labelMap.put(item.getMeterId(), item.getLabel()));
        }
        String s = labelMap.get(meterId);
        if (StringUtils.isEmpty(s)) {
            return null;
        } else return s;
    }

    @Override
    public String tgLabel(String tgNo){
        if (tglabelMap.isEmpty()) {
            tgLoadItemService.list().forEach(item -> tglabelMap.put(item.getTgNo(), item.getLabel()));
        }
        String s = tglabelMap.get(tgNo);
        if (StringUtils.isEmpty(s)) {
            return null;
        } else return "重复停运风险";
    }

    @Override
    public String lineNmLabel(String lineNm){
        if (lineNmlabelMap.isEmpty()) {
            tgLoadItemService.list().forEach(item -> lineNmlabelMap.put(item.getLineNm(), item.getLabel()));
        }
        String s = lineNmlabelMap.get(lineNm);
        if (StringUtils.isEmpty(s)) {
            return null;
        } else return "重复停运风险";
    }

    public static void main(String[] args) {
        System.out.println(NumberUtil.round("2.335235", 2));
    }

    private static int getNotNull(String[] resultMaped) {
        for (int i = 96; i >= 1; i--) {
            if (resultMaped[i] != null) {
                return i;
            }
        }
        return 0;
    }

    private String getKey(String meterId, String dataType, String dataDt) {
        return meterId + "_" + dataType + "_" + dataDt;
    }
}




